﻿using System;
using Echo.Context.UltiProNet.Contexts;
using Echo.Core.Common;
using Echo.Core.TestAbstraction.WebUITest.MbUnit;
using Echo.Models.UltimateSoftware;
using Echo.Models.UltimateSoftware.WebUITest.MbUnit;
using MbUnit.Framework;

////*************************************************************************************************************************************
////Created by: Ruben Martinez (SWAT)
////Date created: 09/08/2011
////Modified by: David Mello (Echo conversion)
////Date modified: 07/12/2013
////Reason: 
////ULTI-59093 As Patricia the WorkPlace payroll administrator I want the a section on the W-2 Print Approval page which allows me to identify
////           multiple email addresses to receive W-2 status notifications from the W-2 forms print vendor and to identify an UltiPro user to
////           receive the Employer Copy D PDF format file.
////ULTI-59097 As Patricia the WorkPlace payroll administrator I want to enter an email address for an employee to be notified of any W-2 print statuses. 
////ULTI-59102 As Patricia the WorkPlace payroll administrator I want to identify an additional email address to recieve W-2 print service status notifications. 
////ULTI-59115 As Patricia the WorkPlace payroll administrator I want to identify a second additional email address to recieve W-2 print service status notifications.
////ULTI-59120 As Patricia the WorkPlace payroll administrator I want to enter multiple email addresses in order, primary, addtional 1 and finally additional 2. 
////*************************************************************************************************************************************

namespace Echo.Automation.Payroll.W2_Print_Approval
{
    [TestFixture]
    [Author("David Mello", "david_mello@ultimatesoftware.com")]
    [Category("W2 Print Approval")]
    [Release("10.7.1")]
    [Header("Config")]
    [Config(".NET")]
    public class W2PrintApprovalW2Notifications : MbUnitAutomatedTest
    {
        UltiPro ultiPro;
        UltiProDatabaseContext database;

        [FixtureSetUp]
        public void FixtureSetUp()
        {
            this.ultiPro = Launch<UltiPro>();
            this.database = Init<UltiProDatabaseContext>();
            this.database.Company = ConfigDatabase("ULTIPRO_SB340");
            this.database.Company.AddRollBack("paw2ApprovalDates");
            this.database.Company.AddRollBack("paw2Approvals");

            // Insert record into paw2ApprovalDates to enable print approval.
            this.database.Company.Execute("DELETE FROM paw2ApprovalDates WHERE paaYear IN (2008, 2009)");
            this.DeleteShippingPreference("TAX4");
            this.database.Company.Execute(string.Format(
                "INSERT INTO paw2ApprovalDates (paaFinalApprovalDate, paaYear) VALUES ('{0}',2008)",
                DateTime.Now.AddDays(1).ToShortDateString()));

            // Login and click Reporting > W2 Print Approval.
            this.ultiPro.Pages.Login.LoginAs("BlackM", "password", Config.LanguageCode);
        }

        [FixtureTearDown]
        public void FixtureTearDown()
        {
            this.database.Company.RollBackDatabase();
            this.ultiPro.Browser.Quit();
        }

        [SetUp]
        public void TestSetup()
        {
            this.ultiPro.Menu.Reporting.Click(link => link.W2PrintApproval);
            this.ultiPro.Pages.W2PrintApprovalSummary.W2PrintApprovalSummaryGrid.Row(row => row.TaxGroupLink, "TAX4").Click(link => link.TaxGroupLink);
        }

        [TearDown]
        public void TestTearDown()
        {
            DeleteShippingPreference("TAX4");
        }

        /// <summary>
        /// ULTI-59097 - Verify Primary email address text is present and box right next to its a required/enabled field.
        /// <see cref="http://devspiratest01/SpiraTest/33/TestCase/145331/TestSteps.aspx"/>
        /// </summary>
        [Test]
        public void PrimaryEmailLabeledAndRequired()
        {
            // Given I am on the W2PrintApprovalDetails page.

            // The Primary Email address field should be labeled and required.
            this.ultiPro.Pages.W2PrintApprovalDetail.Is(lbl => lbl.PrimaryEmailAddressLabel, "innerHtml", ultiPro.Localization.Strings.Primary_Email_Address.ToTitleCase());
            this.ultiPro.Pages.W2PrintApprovalDetail.Required(tb => tb.PrimaryEmailAddressTextBox);
        }

        /// <summary>
        /// ULTI-59133 - Verify Employer Copy D Recipient text is present and drop-down box right next to its a required/enabled field.
        /// <see cref="http://devspiratest01/SpiraTest/33/TestCase/145661/TestSteps.aspx"/>
        /// </summary>
        [Test]
        public void CopyDRecipientRequired()
        {
            // Given I am on the W2PrintApprovalDetails page.

            // The Employer COpy D Recipient select list should be labeled and required.
            this.ultiPro.Pages.W2PrintApprovalDetail.Is(lbl => lbl.CopyRecipientsLabel, "innerHtml", ultiPro.Localization.Strings.Employer_Copy_D_Recipient.ToTitleCase());
            this.ultiPro.Pages.W2PrintApprovalDetail.Required(select => select.CopyRecipientsDropDown);
        }

        /// <summary>
        /// ULTI-59120 - Verify Additional Email Address 1 and 2 fields are disabled
        /// <see cref="http://devspiratest01/SpiraTest/33/TestCase/145505/TestSteps.aspx"/>
        /// </summary>
        [Test]
        public void AdditionalEmailAddressFieldsDisabledInitially()
        {
            // Given I am on the W2PrintApprovalDetails page.

            // Then the additional email text boxes are labeled and disabled.
            this.ultiPro.Pages.W2PrintApprovalDetail.Is(lbl => lbl.AdditionalEmailAddress1Label, "innerHtml", ultiPro.Localization.Strings.Additional_Email_Address_1.ToTitleCase());
            this.ultiPro.Pages.W2PrintApprovalDetail.NotEnabled(tb => tb.AdditionalEmailAddress1TextBox);

            this.ultiPro.Pages.W2PrintApprovalDetail.Is(lbl => lbl.AdditionalEmailAddress2Label, "innerHtml", ultiPro.Localization.Strings.Additional_Email_Address_2.ToTitleCase());
            this.ultiPro.Pages.W2PrintApprovalDetail.NotEnabled(tb => tb.AdditionalEmailAddress2TextBox);
        }

        /// <summary>
        /// ULTI-59120 - The first additional email address textbox should remain disabled until a valid primary email is entered.
        /// <see cref="http://devspiratest01/SpiraTest/33/TestCase/145506/TestSteps.aspx"/>
        /// </summary>
        [Test]
        public void AdditionalEmail1RemainsDisabledUntilValidPrimaryEmailEntered()
        {
            // Given I am on the W2PrintApprovalDetails page.

            // When I enter an invalid primary email.
            this.ultiPro.Pages.W2PrintApprovalDetail.Set(tb => tb.PrimaryEmailAddressTextBox, "a@b.c");

            // Then the additional email text boxes remain disabled.
            this.ultiPro.Pages.W2PrintApprovalDetail.NotEnabled(tb => tb.AdditionalEmailAddress1TextBox);
            this.ultiPro.Pages.W2PrintApprovalDetail.NotEnabled(tb => tb.AdditionalEmailAddress2TextBox);

            // And when I change it to a valid email.
            this.ultiPro.Pages.W2PrintApprovalDetail.Set(tb => tb.PrimaryEmailAddressTextBox, "a@b.co");

            // Then the first additional email text box enables.
            this.ultiPro.Pages.W2PrintApprovalDetail.Enabled(tb => tb.AdditionalEmailAddress1TextBox);
            this.ultiPro.Pages.W2PrintApprovalDetail.NotEnabled(tb => tb.AdditionalEmailAddress2TextBox);
        }

        /// <summary>
        /// ULTI-59097 - Verifies entering an invalid email address produces a validation error and blocks the database save.
        /// Summarizes tests 7 through 11 in old SWAT script.
        /// </summary>
        [Test]
        [Row("a@b...")]
        [Row("ab.c#!26.3@ran.dom.")]
        [Row("1@-.com")]
        public void InvalidEmailProducesError(string email)
        {
            // Given I have entered an invalid primary email on the W2PrintApprovalDetails page.
            this.ultiPro.Pages.W2PrintApprovalDetail.Set(tb => tb.PrimaryEmailAddressTextBox, email);
            // And a valid copy d recipient
            this.ultiPro.Pages.W2PrintApprovalDetail.Set(x => x.CopyRecipientsDropDown, "ARTRIPL1", SelectOption.Value);

            // When I click Save.
            this.ultiPro.Pages.W2PrintApprovalDetail.ButtonBar.Click(b => b.Save);

            // Then I should receive an error.
            this.ultiPro.Pages.W2PrintApprovalDetail.ErrorMessages.Like(e => e.MessageBox, "innerHtml", "E-mail has invalid format");
            // And the record should not persist to the database.
            Assert.AreEqual("0", this.database.Company.GetValue("SELECT COUNT(*) FROM paw2approvals WHERE pawTaxGroup = 'TAX4'"));
        }

        /// <summary>
        /// ULTI-59097 - Verifies saving with a valid email produces no errors and saves the approval record to the database.
        /// <see cref="http://devspiratest01/SpiraTest/33/TestCase/145591/TestSteps.aspx"/>
        /// <see cref="http://devspiratest01/SpiraTest/33/TestCase/145594/TestSteps.aspx"/>
        /// </summary>
        [Test]
        public void ValidEmailSavesWithoutError()
        {
            // Given I have entered a valid primary email on the W2PrintApprovalDetails page.
            this.ultiPro.Pages.W2PrintApprovalDetail.Set(tb => tb.PrimaryEmailAddressTextBox, "a-long-e(ai)_addr*ss!#.&@A_FORTUNE500COMPANY.CO.UK");
            // And a valid copy d recipient
            this.ultiPro.Pages.W2PrintApprovalDetail.Set(x => x.CopyRecipientsDropDown, "ARTRIPL1", SelectOption.Value);

            // When I click Save.
            this.ultiPro.Pages.W2PrintApprovalDetail.ButtonBar.Click(b => b.Save);

            // No error should be present.
            this.ultiPro.Pages.W2PrintApprovalDetail.ErrorMessages.NotVisibleOrNotExists(e => e.MessageBox);
            // And the value should be persisted to the database.
            Assert.AreEqual("1",
                this.database.Company.GetValue("SELECT COUNT(*) FROM paw2approvals WHERE pawTaxGroup = 'TAX4' AND pawEmailAddress = 'a-long-e(ai)_addr*ss!#.&@A_FORTUNE500COMPANY.CO.UK' AND pawRecipientUserID = 'ARTRIPL1' AND pawEmailAddress1 IS NULL AND pawEmailAddress2 IS NULL"));
        }

        [Test]
        public void AdditionalEmailEnabledAfterSaveOfValidPrimaryEmail()
        {
            // Given W2PrintApprovalDetails page was saved with a valid primary email.
            this.ultiPro.Pages.W2PrintApprovalDetail.Set(tb => tb.PrimaryEmailAddressTextBox, "a-long-email-address1112@A_FORTUNE500COMPANY.CO.UK");
            this.ultiPro.Pages.W2PrintApprovalDetail.Set(x => x.CopyRecipientsDropDown, "ARTRIPL1", SelectOption.Value);
            this.ultiPro.Pages.W2PrintApprovalDetail.ButtonBar.Click(b => b.Save);

            // When I revisit the page.
            this.ultiPro.Pages.W2PrintApprovalSummary.W2PrintApprovalSummaryGrid.Row(row => row.TaxGroupLink, "TAX4").Click(link => link.TaxGroupLink);

            // The primary email will preload, the first alternate email will be enabled, and second alternate email disabled.
            this.ultiPro.Pages.W2PrintApprovalDetail.Is(tb => tb.PrimaryEmailAddressTextBox, "value", "a-long-email-address1112@A_FORTUNE500COMPANY.CO.UK");
            this.ultiPro.Pages.W2PrintApprovalDetail.Enabled(tb => tb.AdditionalEmailAddress1TextBox);
            this.ultiPro.Pages.W2PrintApprovalDetail.NotEnabled(tb => tb.AdditionalEmailAddress2TextBox);
        }

        [Test]
        public void AdditionalEmail1IsValidated()
        {
            // Given I have entered a valid primary email on the W2PrintApprovalDetails page.
            this.ultiPro.Pages.W2PrintApprovalDetail.Set(tb => tb.PrimaryEmailAddressTextBox, "a@b.com");
            // And a valid copy d recipient
            this.ultiPro.Pages.W2PrintApprovalDetail.Set(x => x.CopyRecipientsDropDown, "ARTRIPL1", SelectOption.Value);

            // When I enter an invalid additional email address and click Save.
            this.ultiPro.Pages.W2PrintApprovalDetail.Set(tb => tb.AdditionalEmailAddress1TextBox, "@test.org");
            this.ultiPro.Pages.W2PrintApprovalDetail.ButtonBar.Click(b => b.Save);

            // Then I should receive an error.
            this.ultiPro.Pages.W2PrintApprovalDetail.ErrorMessages.Like(e => e.MessageBox, "innerHtml", "E-mail has invalid format");
            // And the record should not persist to the database.
            Assert.AreEqual("0", this.database.Company.GetValue("SELECT COUNT(*) FROM paw2approvals WHERE pawTaxGroup = 'TAX4'"));
        }

        [Test]
        public void AdditionalEmail2IsValidated()
        {
            // Given I have entered a valid primary and secondary email on the W2PrintApprovalDetails page.
            this.ultiPro.Pages.W2PrintApprovalDetail.Set(tb => tb.PrimaryEmailAddressTextBox, "a@b.com");
            this.ultiPro.Pages.W2PrintApprovalDetail.Set(tb => tb.AdditionalEmailAddress1TextBox, "valid@test.org");
            // And a valid copy d recipient
            this.ultiPro.Pages.W2PrintApprovalDetail.Set(x => x.CopyRecipientsDropDown, "ARTRIPL1", SelectOption.Value);

            // When I enter an invalid additional email address and click Save.
            this.ultiPro.Pages.W2PrintApprovalDetail.Set(tb => tb.AdditionalEmailAddress2TextBox, ">invalid@test.org");
            this.ultiPro.Pages.W2PrintApprovalDetail.ButtonBar.Click(b => b.Save);

            // Then I should receive an error.
            this.ultiPro.Pages.W2PrintApprovalDetail.ErrorMessages.Like(e => e.MessageBox, "innerHtml", "E-mail has invalid format");
            // And the record should not persist to the database.
            Assert.AreEqual("0", this.database.Company.GetValue("SELECT COUNT(*) FROM paw2approvals WHERE pawTaxGroup = 'TAX4'"));
        }

        [Test]
        public void AdditionalEmailAddressesArePersisted()
        {
            // Given I have entered a valid primary, secondary, and tertiary email on the W2PrintApprovalDetails page.
            this.ultiPro.Pages.W2PrintApprovalDetail.Set(tb => tb.PrimaryEmailAddressTextBox, "a-long-email-address1112@A_FORTUNE500COMPANY.CO.UK");
            this.ultiPro.Pages.W2PrintApprovalDetail.Set(tb => tb.AdditionalEmailAddress1TextBox, "alt1@test.org");
            this.ultiPro.Pages.W2PrintApprovalDetail.Set(tb => tb.AdditionalEmailAddress2TextBox, "alt2@test.org");
            // And a valid copy d recipient
            this.ultiPro.Pages.W2PrintApprovalDetail.Set(x => x.CopyRecipientsDropDown, "ARTRIPL1", SelectOption.Value);

            // When I click Save.
            this.ultiPro.Pages.W2PrintApprovalDetail.ButtonBar.Click(b => b.Save);

            // Then no error should be present.
            this.ultiPro.Pages.W2PrintApprovalDetail.ErrorMessages.NotVisibleOrNotExists(e => e.MessageBox);
            // And the value should be persisted to the database.
            Assert.AreEqual("1",
                this.database.Company.GetValue("SELECT COUNT(*) FROM paw2approvals WHERE pawTaxGroup = 'TAX4' AND pawEmailAddress = 'a-long-email-address1112@A_FORTUNE500COMPANY.CO.UK' AND pawRecipientUserID = 'ARTRIPL1' AND pawEmailAddress1 = 'alt1@test.org' AND pawEmailAddress2 = 'alt2@test.org'"));
            
            // And when the page is revisited.
            this.ultiPro.Pages.W2PrintApprovalSummary.W2PrintApprovalSummaryGrid.Row(row => row.TaxGroupLink, "TAX4").Click(link => link.TaxGroupLink);

            // Then the saved email information should be preloaded.
            this.ultiPro.Pages.W2PrintApprovalDetail.Is(tb => tb.PrimaryEmailAddressTextBox, "value", "a-long-email-address1112@A_FORTUNE500COMPANY.CO.UK");
            this.ultiPro.Pages.W2PrintApprovalDetail.Is(tb => tb.AdditionalEmailAddress1TextBox, "value", "alt1@test.org");
            this.ultiPro.Pages.W2PrintApprovalDetail.Is(tb => tb.AdditionalEmailAddress2TextBox, "value", "alt2@test.org");
        }

        private void DeleteShippingPreference(string taxGroup)
        {
            this.database.Company.Execute(string.Format("DELETE FROM paw2approvals WHERE pawTaxGroup = '{0}'", taxGroup));
        }
    }
}
